package com.huawei.codecheck.uccp.plugin.cangjie;

import com.huawei.codecheck.uccp.api.bean.cmd.CommandInfo;
import com.huawei.codecheck.uccp.api.bean.cmd.CommandResult;
import com.huawei.codecheck.uccp.api.bean.param.ToolParameterInfo;
import org.apache.commons.exec.CommandLine;
import org.apache.commons.lang3.SystemUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Arrays;
import java.util.List;

public class Cjlint extends ToolParameterInfo {
    private String exec_cjlint;
    private ArrayList<String> excluded;
    private String output;
    private String report = "json";
    private String config;
    private String modules;
    private String filesDir;
    protected final Logger LOG;
    public Cjlint() {
        this.excluded = new ArrayList<>();
        LOG = LoggerFactory.getLogger(this.getClass());
    }


    public void setCangjiePath(String path){
        this.exec_cjlint = path + File.separator + "tools" + File.separator + "bin" + File.separator + "cjlint";
        ExecUtils.setCangjiePath(path);
    }

    public int exec() {
        ArrayList<String> sb = new ArrayList<String>();
        if (filesDir == null){
            return 1;
        }
        sb.add(exec_cjlint);
        sb.add("-f");
        LOG.info("添加filesDir: {}", filesDir);
        sb.add(filesDir);
        sb.add("-r");
        LOG.info("添加report: {}", report);
        sb.add(report);
// TODO
//        for (int i = 0; i < excluded.size(); i++) {
//
//        }
        sb.add("-o");
        LOG.info("添加output: {}", output);
        sb.add(output);
        LOG.info("执行命令size: {}", sb.size());
        String[] strings = new String[sb.size()];
        sb.toArray(strings);
        LOG.info("执行命令: {}", Arrays.toString(strings).replace("/", "//"));
        return ExecUtils.run(strings);
    }

    public CommandResult getCommand() {
        StringBuilder sb = new StringBuilder();
        if (filesDir == null){
            return new CommandResult(null, new ArrayList<String>());
        }
        LOG.info("添加filesDir: {}", filesDir);
        LOG.info("添加report: {}", report);
        LOG.info("添加output: {}", output);
        sb.append(exec_cjlint);
        sb.append(" ");
        sb.append("-f");
        sb.append(" ");
        sb.append(filesDir);
        sb.append(" ");
        sb.append("-r");
        sb.append(" ");
        sb.append(report);
        // TODO
//        for (int i = 0; i < excluded.size(); i++) {
//
//        }
        sb.append(" ");
        sb.append("-o");
        sb.append(" ");
        sb.append(output);
//        LOG.info("执行命令size: {}", sb);
//        String[] strings = new String[sb.size()];
//        sb.toArray(strings);
        LOG.info("执行命令: {}", sb.toString().replace("/", "//"));
        List<CommandInfo> commandInfos = new ArrayList();

        CommandLine cmdLine = CommandLine.parse(sb.toString());

        commandInfos.add(new CommandInfo(cmdLine, output));
        return new CommandResult(commandInfos, new ArrayList<String>());
    }

    public String getFilesDir() {
        return filesDir;
    }

    public void setFilesDir(String filesDir) {
        this.filesDir = filesDir;
    }

    public String getModules() {
        return modules;
    }

    public void setModules(String modules) {
        this.modules = modules;
    }

    public String getConfig() {
        return config;
    }

    public void setConfig(String config) {
        this.config = config;
    }

    public String getReport() {
        return report;
    }

    public void setReport(String report) {
        this.report = report;
    }

    public String getOutput() {
        return output;
    }

    public void setOutput(String output) {
        this.output = output;
    }

    public ArrayList<String> getExcluded() {
        return excluded;
    }

    public void setExcluded(ArrayList<String> excluded) {
        this.excluded = excluded;
    }


    /**
     * 读取文件中指定行及其上下各contextLines行的内容
     * @param filePath 文件路径
     * @param targetLine 目标行号(从1开始)
     * @param contextLines 上下文的行数
     * @return 包含目标行及其上下文的字符串列表
     */
    public static String readWithContext(String filePath, int targetLine, int contextLines) {
        // 参数验证
        if (targetLine < 1) {
            throw new IllegalArgumentException("行号必须大于0");
        }
        if (contextLines < 0) {
            throw new IllegalArgumentException("上下文行数不能为负数");
        }

        List<String> result = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
            String line;
            int currentLine = 0;
            LinkedList<String> buffer = new LinkedList<>();

            while ((line = reader.readLine()) != null) {
                currentLine++;
                buffer.add(line);

                // 当缓冲区超过需要的大小时，移除最早的行
                if (buffer.size() > contextLines * 2 + 1) {
                    buffer.removeFirst();
                }

                // 当到达目标行时，收集结果
                if (currentLine == targetLine) {
                    // 添加缓冲区中已读取的行
                    result.addAll(buffer);
                    // 继续读取下面的contextLines行
                    for (int i = 0; i < contextLines && (line = reader.readLine()) != null; i++) {
                        result.add(line);
                    }
                    return String.join("\r\n", result);
                }
            }
        } catch (Exception e) {
            return "";
        }
        return String.join("\r\n", result); // 如果目标行超出文件范围，返回空列表
    }
}
